#include <sys/types.h>
#include <unistd.h>
#include <ctime>

#include "BlockQueue.hpp"
#include "Task.hpp"

template<class C,class S>
class BlockQueues
{
public:
    BlockQueue<C>* c_bq;
    BlockQueue<S>* s_bq;
};
void* productor(void* args) //生产者线程
{
    BlockQueue<CalTask>* bq = (static_cast<BlockQueues<CalTask,SaveTask>*>(args))->c_bq;
    while(true)
    {
        //生产活动
        
        int x = rand()%10+1;
        int y = rand()%5;
        int operidx = rand()% oper.size();  //运算符下标

        CalTask t(x,y,oper[operidx],mymath);
        bq->push(t);

        cout<< "生产任务：" << t.to_Task_string() << endl;
        sleep(1);

    }
    return nullptr;
}
void* consumer(void* args)  //消费者线程
{
    BlockQueue<CalTask>* bq = (static_cast<BlockQueues<CalTask,SaveTask>*>(args))->c_bq;
    BlockQueue<SaveTask>* save_bq = (static_cast<BlockQueues<CalTask,SaveTask>*>(args))->s_bq;

    while(true)
    {
        //消费活动
        
        CalTask t;
        bq->pop(&t);
        std::string result = t();
        cout<<"计算任务：" << result << endl;

        SaveTask save(result,Save);
        save_bq->push(save);
        cout<< "推送任务完成..." <<endl;
        // sleep(1);
    }
    return nullptr;
}

void* saver(void* args) //存储任务线程
{
    BlockQueue<SaveTask>* save_bq = (static_cast<BlockQueues<CalTask,SaveTask>*>(args))->s_bq;
    while(true)
    {
        SaveTask st;
        save_bq->pop(&st);
        st();
        cout<< "保存任务完成..." <<endl;
        
    }
    return nullptr;
}

// int main()
// {
//     srand((unsigned long)time(0) ^ getpid());
//     BlockQueues<CalTask,SaveTask> bqs;

//     bqs.c_bq = new BlockQueue<CalTask>();
//     bqs.s_bq = new BlockQueue<SaveTask>();

//     pthread_t c[2],p[3];
//     pthread_create(p,nullptr,productor,&bqs);
//     pthread_create(p+1,nullptr,productor,&bqs);
//     pthread_create(p+2,nullptr,productor,&bqs);
//     pthread_create(c,nullptr,consumer,&bqs);
//     pthread_create(c+1,nullptr,consumer,&bqs);

//     pthread_join(c[0],nullptr);
//     pthread_join(c[1],nullptr);
//     pthread_join(p[0],nullptr);
//     pthread_join(p[1],nullptr);
//     pthread_join(p[2],nullptr);

//     delete bqs.c_bq;
//     delete bqs.s_bq;
//     return 0;
// }

// 单生产，消费，存储
int main()
{
    srand((unsigned long)time(0) ^ getpid());
    BlockQueues<CalTask,SaveTask> bqs;

    bqs.c_bq = new BlockQueue<CalTask>();
    bqs.s_bq = new BlockQueue<SaveTask>();

    pthread_t c,p,s;
    pthread_create(&p,nullptr,productor,&bqs);
    pthread_create(&c,nullptr,consumer,&bqs);
    pthread_create(&s,nullptr,saver,&bqs);


    pthread_join(c,nullptr);
    pthread_join(p,nullptr);
    pthread_join(s,nullptr);


    delete bqs.c_bq;
    delete bqs.s_bq;

    return 0;
}